#ifndef INDEXEDMESH_H
#define INDEXEDMESH_H

#include "Model/Geometry.h"
#include <OGRE/OgreManualObject.h>

/**
 * \namespace OgreLoader
 * \brief Ogre generators from model
 *
 * This namespace contains the classes responsible for generating 3d objects
 * from the map files. The objects are delivered in the form of Ogre::ManualObject objects.
 * They use openGL immediate mode for rendering.
 */

namespace OgreLoader {
    
/**
 * Mesh with unique-id vertexes.
 * @description This class uses Vertex with indexes starting at 0,
 * as in OpenGL Immediate style. This is used by Ogre'ManualObject
 * to describe a geometry.
 */

/* TODO : Separate IndexedMesh implementation from the Building
 * ManualObject generation.
 */
class IndexedMesh
{
    /**
     * Id-Indexed Vertex.
     */
    class Vertex {
    public:
        /**
	 * Creates a new vertex.
	 * \param id Index of the vertex.
	 * \param x X position.
	 * \param y Y position.
	 */
        Vertex(int id, double x, double y);
        
        int id; ///< Unique index used for OpenGL Immediate mode.
        double x, y;
    };
    
    /**
     * Edge linking two Id-Indexed Vertexes.
     */
    class Edge {
    public:
        /**
	 * Creates a new Edge linking vertex A and vertex B.
	 * \param a First Vertex.
	 * \param b Second Vertex.
	 */
        Edge(int a, int b);
        int v1, v2;
    };
    
    QList<Vertex> vertexes;
    QList<Edge> edges;
    double scale;
    Ogre::String floorMaterial;
    Ogre::String ceilMaterial;
    Ogre::String wallMaterial;
    
public:
    /**
     * Creates a new IndexedMesh from the given Mesh object.
     * \param from a source Mesh.
     * \param scale horizontal scale factor for the target object.
     */
    IndexedMesh(Model::Mesh* from, double scale);
    
    void setFloorMaterial(const Ogre::String& name); ///< [CHANGEME] Sets the material name for the floor.
    void setCeilMaterial(const Ogre::String& name);  ///< [CHANGEME] Sets the material name for the ceil.
    void setWallMaterial(const Ogre::String& name);  ///< [CHANGEME] Sets the material name for the wall.
    
    /**
     * Generates an Ogre ManualObject from the current mesh.
     * \param m Reference to an Ogre SceneManager
     * \param height Height of the object, in target space dimension
     * \param name Name of the generated object.
     */
    Ogre::ManualObject* get(Ogre::SceneManager* m, double height, const char* name);
    
    ~IndexedMesh();
};

}

#endif // INDEXEDMESH_H
